package Logic.Objects;
import Logic.IPoint;
import Logic.Square;

/********************<<< CLASS PlayEngineState >>>*************************/
/* each move can change only 2 squares state,
 * so, remember the state of the 2 squares before the move and after it 
 */
public class PlayEngineState {
	public enum LastOp {
		Redo,
		Undo,
		other,
		none;
	}

	/********************<<< MEMBERS >>>*************************/

	// remember the last operation
	private LastOp	lastOperation;

	private int preCurrentPlayer;

	// coordinates of the 2 squares that have been changed
	private IPoint	coordinateSquare1;
	private IPoint	coordinateSquare2;

	// Previous squares state
	private Square preSquare1; //square1 before the player move
	private Square preSquare2; //square2 before the player move

	/********************<<< OPERATIONS >>>*************************/
	// Constructor
	public PlayEngineState(){
		lastOperation = LastOp.none;
	}

	// support only one undo
	public void undo(PlayEngine engine){
		if (lastOperation != LastOp.Undo)
			switchState(engine);
		lastOperation = LastOp.Undo;
	}

	// support only one redo
	public void redo(PlayEngine engine){
		if (lastOperation == LastOp.Undo)
			switchState(engine);
		lastOperation = LastOp.Redo;
	}

	/**
	 * @Description :
	 * 	Save the current sate of the engine. 
	 *  This call become before any move action, so actually it's gone a be the previous state.
	 * @param :
	 * 	int		preNumberOfPlayers	-  
	 * 	int 	preCurrentPlayer	- current player in the game
	 * 	IPoint	coordinateSquare1	- the coordinates of the square we moved from
	 * 	IPoint	coordinateSquare2	- the coordinates of the square we are moving to
	 */
	public void savePreState(PlayEngine engine, IPoint	coordinateSquare1, IPoint	coordinateSquare2){
		lastOperation = LastOp.other;
		this.coordinateSquare1 = new Point(coordinateSquare1.getX(),coordinateSquare1.getY());
		this.coordinateSquare2 = new Point(coordinateSquare2.getX(),coordinateSquare2.getY());
		engine.getNumberOfPlayers();
		this.preCurrentPlayer = engine.getCurrentPlayer(-1);
		this.preSquare1 = engine.getBoardXY(coordinateSquare1.getX(), coordinateSquare1.getY()).duplicateInstance();
		this.preSquare2 = engine.getBoardXY(coordinateSquare2.getX(), coordinateSquare2.getY()).duplicateInstance();
	}

	// if it's the beginning of the game: lastOperation == LastOp.none
	// don't do anything
	/**
	 * @Description :
	 * 	Save the current sate of the engine. 
	 *  restore the previous saved state to the engine.
	 */
	public void switchState(PlayEngine engine){
		if (lastOperation != LastOp.none){
			int currCurrentPlayer;
			Square currSquare1;
			Square currSquare2;

			currCurrentPlayer = engine.getCurrentPlayer(-1);
			currSquare1 = engine.getBoardXY(coordinateSquare1.getX(), coordinateSquare1.getY()).duplicateInstance();
			currSquare2 = engine.getBoardXY(coordinateSquare2.getX(), coordinateSquare2.getY()).duplicateInstance();

			// restore engine state
			engine.setBoardXY(preSquare1.duplicateInstance(), coordinateSquare1.getX(), coordinateSquare1.getY());
			engine.setBoardXY(preSquare2.duplicateInstance(), coordinateSquare2.getX(), coordinateSquare2.getY());

			engine.setCurrentPlayer(preCurrentPlayer);

			// the Previous is that that was the current
			preSquare1 = currSquare1.duplicateInstance();
			preSquare2 = currSquare2.duplicateInstance();

			preCurrentPlayer = currCurrentPlayer;


		}
	}
}

